home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DJGPP / CBGRX103.ZIP / contrib / libgrx / src / cursor.c < prev    next >
Text File  |  1993-12-06  |  8KB  |  281 lines

  1. /**
  2.  ** CURSOR.C
  3.  **
  4.  **  Copyright (C) 1992, Csaba Biegl
  5.  **    820 Stirrup Dr, Nashville, TN, 37221
  6.  **    csaba@vuse.vanderbilt.edu
  7.  **
  8.  **  This file is distributed under the terms listed in the document
  9.  **  "copying.cb", available from the author at the address above.
  10.  **  A copy of "copying.cb" should accompany this file; if not, a copy
  11.  **  should be available from where this file was obtained.  This file
  12.  **  may not be distributed without a verbatim copy of "copying.cb".
  13.  **  You should also have received a copy of the GNU General Public
  14.  **  License along with this program (it is in the file "copying");
  15.  **  if not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  16.  **  Cambridge, MA 02139, USA.
  17.  **
  18.  **  This program is distributed in the hope that it will be useful,
  19.  **  but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.  **  GNU General Public License for more details.
  22.  **/
  23.  
  24. #include "grx.h"
  25. #include "mousex.h"
  26. #include "libgrx.h"
  27. #include "gmalloc.h"
  28.  
  29.  
  30. GrCursor *_GrMouseCursor = NULL;
  31.  
  32. GrCursor *GrBuildCursor(char *bits,int w,int h,int xo,int yo,GrColorTableP ct)
  33. {
  34.     GrCursor  *c = _GrMalloc(sizeof(GrCursor));
  35.     GrContext save,work;
  36.     unsigned  char *bp;
  37.     int  workw = (w + w + 15) & ~7;
  38.     int  workh = (h + h + 7) & ~1;
  39.     long csize = GrContextSize(w,h);
  40.     long wsize = GrContextSize(workw,workh);
  41.     int  ww,hh,color,onscreen = FALSE;
  42.     char far *vdata = NULL;
  43.     char far *data;
  44.     long addr;
  45.  
  46.     if(c == NULL) return(NULL);
  47. #if !defined(__GNUC__) || (__GNUC__ != 2)
  48.     /* something is fishy in GCC 2.0 at this time !! */
  49.     /* maybe I will chase it down if I have enough time */
  50. #if (GRXPLANES & 4)
  51.     if(_GrNumColors == 16) {
  52.         long wsize2 = GrPlaneSize(workw,workh);
  53.         vdata = _GrVidAlloc((int)(2 * wsize2));
  54.         if(vdata != (char far *)NULL) {
  55.         onscreen = TRUE;
  56.         wsize = wsize2;
  57.         }
  58.     }
  59. #endif
  60. #endif
  61.     data = _GrFarMalloc((csize + (onscreen ? 0L : wsize)) * 2);
  62.     if(data == (char far *)NULL) {
  63.         _GrFree(c);
  64.         if(onscreen) _GrVidFree(vdata);
  65.         return(NULL);
  66.     }
  67.  
  68.     c->cr_xcord = c->cr_ycord = 0;
  69.     c->cr_xwpos = c->cr_ywpos = 0;
  70.     c->cr_xsize = w;
  71.     c->cr_ysize = h;
  72.     c->cr_xoffs = xo;
  73.     c->cr_yoffs = yo;
  74.     c->cr_xwork = workw;
  75.     c->cr_ywork = workh;
  76.     c->cr_displayed = FALSE;
  77.  
  78.     GrSaveContext(&save);
  79.  
  80.     GrCreateContext(w,h,data,&work);
  81.     data = (char far *)((char huge *)data + csize);
  82.     GrSetContext(&work);
  83.     bp = (unsigned char *)bits;
  84.     for(hh = 0; hh < h; hh++) {
  85.         addr = PIXEL_ADDR(0,hh);
  86.         _GrSetPixRow(addr,C_COLOR,w);
  87.         for(ww = 0; ww < w; ww++) {
  88.         if(*bp++ != 0) _GrSetPixel(addr,0);
  89.         addr += PIXEL_SIZE;
  90.         }
  91.     }
  92.     c->cr_andmask = *((GrVidRAM *)&work);
  93.  
  94.     GrCreateContext(w,h,data,&work);
  95.     data = (char far *)((char huge *)data + csize);
  96.     GrSetContext(&work);
  97.     bp = (unsigned char *)bits;
  98.     for(hh = 0; hh < h; hh++) {
  99.         addr = PIXEL_ADDR(0,hh);
  100.         _GrSetPixRow(addr,0,w);
  101.         for(ww = 0; ww < w; ww++) {
  102.         if((color = *bp++) != 0) {
  103.             color--;
  104.             if(ct != NULL) color = GR_CTABLE_COLOR(ct,color);
  105.             _GrSetPixel(addr,(color & C_COLOR));
  106.         }
  107.         addr += PIXEL_SIZE;
  108.         }
  109.     }
  110.     c->cr_ormask = *((GrVidRAM *)&work);
  111.  
  112.     if(!onscreen) vdata = data;
  113.  
  114.     GrCreateContext(workw,workh,vdata,&work);
  115.     vdata = (char far *)((char huge *)vdata + wsize);
  116.     c->cr_work = *((GrVidRAM *)&work);
  117.     if(onscreen) {
  118.         c->cr_work.gc_onscreen = TRUE;
  119.         c->cr_work.gc_planeoffset = 0L;
  120.     }
  121.  
  122.     GrCreateContext(workw,workh,vdata,&work);
  123.     c->cr_save = *((GrVidRAM *)&work);
  124.     if(onscreen) {
  125.         c->cr_save.gc_onscreen = TRUE;
  126.         c->cr_save.gc_planeoffset = 0L;
  127.     }
  128.  
  129.     GrSetContext(&save);
  130.     return(c);
  131. }
  132.  
  133. void GrDestroyCursor(GrCursor *cursor)
  134. {
  135.     if(cursor && (cursor != _GrMouseCursor)) {
  136.         GrEraseCursor(cursor);
  137.         _GrFarFree(cursor->cr_andmask.gc_baseaddr);
  138.         if(cursor->cr_work.gc_onscreen)
  139.         _GrVidFree(cursor->cr_work.gc_baseaddr);
  140.         _GrFree(cursor);
  141.     }
  142. }
  143.  
  144. void GrDisplayCursor(GrCursor *cursor)
  145. {
  146.     int xpos,ypos;
  147.     int xwrk,ywrk;
  148.     int xsiz,ysiz;
  149.  
  150.     if(cursor->cr_displayed) return;
  151.     cursor->cr_displayed = TRUE;
  152.     xpos = cursor->cr_xcord - cursor->cr_xoffs;
  153.     ypos = cursor->cr_ycord - cursor->cr_yoffs;
  154.     xsiz = cursor->cr_xwork;
  155.     ysiz = cursor->cr_ywork;
  156.     xwrk = (xpos - (cursor->cr_xsize >> 1)) & ~7;
  157.     ywrk = (ypos - (cursor->cr_ysize >> 1));
  158.     if(xwrk < 0) xwrk = 0;
  159.     if(ywrk < 0) ywrk = 0;
  160.     if(xwrk > (_GrScreenX - xsiz)) xwrk = _GrScreenX - xsiz;
  161.     if(ywrk > (_GrScreenY - ysiz)) ywrk = _GrScreenY - ysiz;
  162.     cursor->cr_xwpos = xwrk;
  163.     cursor->cr_ywpos = ywrk;
  164.     _GrPixCopy((GrContext *)&cursor->cr_save,
  165.         PIX_ADDR(&cursor->cr_save,0,0),
  166.         SCREEN,
  167.         PIX_ADDR(SCREEN,xwrk,ywrk),
  168.         xsiz,ysiz,
  169.         GrWRITE
  170.     );
  171.     _GrPixCopy((GrContext *)&cursor->cr_work,
  172.         PIX_ADDR(&cursor->cr_work,0,0),
  173.         (GrContext *)&cursor->cr_save,
  174.         PIX_ADDR(&cursor->cr_save,0,0),
  175.         xsiz,ysiz,
  176.         GrWRITE
  177.     );
  178.     xpos -= xwrk;
  179.     ypos -= ywrk;
  180.     xsiz = cursor->cr_xsize;
  181.     ysiz = cursor->cr_ysize;
  182.     xwrk = ywrk = 0;
  183.     if(xpos < 0) { xwrk -= xpos; xsiz += xpos; xpos = 0; }
  184.     if(ypos < 0) { ywrk -= ypos; ysiz += ypos; ypos = 0; }
  185.     if(xsiz > (cursor->cr_xwork - xpos)) xsiz = cursor->cr_xwork - xpos;
  186.     if(ysiz > (cursor->cr_ywork - ypos)) ysiz = cursor->cr_ywork - ypos;
  187.     if((xsiz <= 0) || (ysiz <= 0)) return;
  188.     _GrPixCopy((GrContext *)&cursor->cr_work,
  189.         PIX_ADDR(&cursor->cr_work,xpos,ypos),
  190.         (GrContext *)&cursor->cr_andmask,
  191.         PIX_ADDR(&cursor->cr_andmask,xwrk,ywrk),
  192.         xsiz,ysiz,
  193.         GrAND
  194.     );
  195.     _GrPixCopy((GrContext *)&cursor->cr_work,
  196.         PIX_ADDR(&cursor->cr_work,xpos,ypos),
  197.         (GrContext *)&cursor->cr_ormask,
  198.         PIX_ADDR(&cursor->cr_ormask,xwrk,ywrk),
  199.         xsiz,ysiz,
  200.         GrOR
  201.     );
  202.     xpos = cursor->cr_xwpos;
  203.     ypos = cursor->cr_ywpos;
  204.     _GrPixCopy(SCREEN,
  205.         PIX_ADDR(SCREEN,xpos,ypos),
  206.         (GrContext *)&cursor->cr_work,
  207.         PIX_ADDR(&cursor->cr_work,0,0),
  208.         cursor->cr_xwork,cursor->cr_ywork,
  209.         GrWRITE
  210.     );
  211. }
  212.  
  213. void GrEraseCursor(GrCursor *cursor)
  214. {
  215.     int xpos = cursor->cr_xwpos;
  216.     int ypos = cursor->cr_ywpos;
  217.  
  218.     if(cursor->cr_displayed) {
  219.         _GrPixCopy(SCREEN,
  220.         PIX_ADDR(SCREEN,xpos,ypos),
  221.         (GrContext *)&cursor->cr_save,
  222.         PIX_ADDR(&cursor->cr_save,0,0),
  223.         cursor->cr_xwork,cursor->cr_ywork,
  224.         GrWRITE
  225.         );
  226.         cursor->cr_displayed = FALSE;
  227.     }
  228. }
  229.  
  230. void GrMoveCursor(GrCursor *cursor,int x,int y)
  231. {
  232.     int xpos,ypos;
  233.     int xsiz,ysiz;
  234.  
  235.     if((cursor->cr_xcord == x) && (cursor->cr_ycord == y)) return;
  236.     cursor->cr_xcord = x;
  237.     cursor->cr_ycord = y;
  238.     if(!cursor->cr_displayed) return;
  239.     xpos = x - cursor->cr_xoffs - cursor->cr_xwpos;
  240.     ypos = y - cursor->cr_yoffs - cursor->cr_ywpos;
  241.     xsiz = cursor->cr_xsize;
  242.     ysiz = cursor->cr_ysize;
  243.     if((xpos >= 0) && ((xpos + xsiz) <= cursor->cr_xwork) &&
  244.        (ypos >= 0) && ((ypos + ysiz) <= cursor->cr_ywork)) {
  245.         _GrPixCopy((GrContext *)&cursor->cr_work,
  246.         PIX_ADDR(&cursor->cr_work,0,0),
  247.         (GrContext *)&cursor->cr_save,
  248.         PIX_ADDR(&cursor->cr_save,0,0),
  249.         cursor->cr_xwork,cursor->cr_ywork,
  250.         GrWRITE
  251.         );
  252.         _GrPixCopy((GrContext *)&cursor->cr_work,
  253.         PIX_ADDR(&cursor->cr_work,xpos,ypos),
  254.         (GrContext *)&cursor->cr_andmask,
  255.         PIX_ADDR(&cursor->cr_andmask,0,0),
  256.         xsiz,ysiz,
  257.         GrAND
  258.         );
  259.         _GrPixCopy((GrContext *)&cursor->cr_work,
  260.         PIX_ADDR(&cursor->cr_work,xpos,ypos),
  261.         (GrContext *)&cursor->cr_ormask,
  262.         PIX_ADDR(&cursor->cr_ormask,0,0),
  263.         xsiz,ysiz,
  264.         GrOR
  265.         );
  266.         xpos = cursor->cr_xwpos;
  267.         ypos = cursor->cr_ywpos;
  268.         _GrPixCopy(SCREEN,
  269.         PIX_ADDR(SCREEN,xpos,ypos),
  270.         (GrContext *)&cursor->cr_work,
  271.         PIX_ADDR(&cursor->cr_work,0,0),
  272.         cursor->cr_xwork,cursor->cr_ywork,
  273.         GrWRITE
  274.         );
  275.         return;
  276.     }
  277.     GrEraseCursor(cursor);
  278.     GrDisplayCursor(cursor);
  279. }
  280.  
  281.